package com.storlead.sjwt.model;

/**
 * @Author: Timo
 * @Date: 2019/3/21 10:37
 * @Description: 返回的实体类
 */

import com.storlead.sjwt.constants.ResultCode;
import lombok.Data;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 返回 json 响应实体类 及响应编码及响应说明
 *
 * @author blank
 * @since 2018/3/19 上午11:58
 */
@Data
public class Result<T> implements Serializable {

    private static final long serialVersionUID = -8719519193191943764L;

    /**
     * 状态码
     */
    protected int code;
    /**
     * 状态信息
     */
    protected String msg;
    /**
     * 状态信息
     */
    private String callback;
    /**
     * 响应数据
     */
    private T data;
    /**
     * 登陆状态
     */
    private Boolean logined;

    /**
     * 请求是否成功，前端根据此字段来判断是否显示msg
     */
    private Boolean isSuccess = true;

    /**
     * 默认构造成功响应
     */
    public Result() {
        this.code = ResultCode.RESULT_SUCCESS.code;
        this.msg = ResultCode.RESULT_SUCCESS.msg;
        this.callback = null;
        this.data = null;
    }

    /**
     * 默认构造成功响应
     */
    public Result(String callback) {
        this.code = ResultCode.RESULT_SUCCESS.code;
        this.msg = ResultCode.RESULT_SUCCESS.msg;
        this.callback = callback;
        this.data = null;
    }

    /**
     * 默认构造成功响应
     */
    public Result(String callback, boolean isSuccess) {
        this.code = ResultCode.RESULT_SUCCESS.code;
        this.msg = ResultCode.RESULT_SUCCESS.msg;
        this.callback = callback;
        this.data = null;
        this.isSuccess = isSuccess;
    }


    /**
     * 默认构造成功响应
     */
    public Result(boolean isSuccess) {
        this.code = ResultCode.RESULT_SUCCESS.code;
        this.msg = ResultCode.RESULT_SUCCESS.msg;
        this.callback = null;
        this.data = null;
        this.isSuccess = isSuccess;
    }

    /**
     * 默认构造成功响应
     */
    public Result(String callback, boolean isSuccess, boolean pageable) {
        this.code = ResultCode.RESULT_SUCCESS.code;
        this.msg = ResultCode.RESULT_SUCCESS.msg;
        this.callback = callback;
        this.data = null;
        this.isSuccess = isSuccess;
    }

    /**
     * 构造成功响应 及泛型
     */
    public Result(T data) {
        this.code = ResultCode.RESULT_SUCCESS.code;
        this.msg = ResultCode.RESULT_SUCCESS.msg;
        this.callback = null;
        this.data = data;
        this.isSuccess = false;
    }


    /**
     * 构造响应
     *
     * @param code 响应码
     * @param msg  对应消息
     * @param data 响应数据
     * @author blank
     * @since 2018/3/19 下午12:27
     */
    public Result(int code, String msg, String callback, T data) {
        this.code = code;
        this.msg = msg;
        this.callback = callback;
        this.data = data;
        this.isSuccess = isSuccess(code);
    }

    /**
     * 根据 code 返回是否成功
     *
     * @param code 返回码
     * @return true or false
     * @author blank
     * @since 2018/5/24 上午11:56
     */
    private Boolean isSuccess(int code) {

        ResultCode[] values = ResultCode.values();
        for (ResultCode resultCode : values) {

            if (resultCode.code == code) {
                return resultCode.isSuccess;
            }
        }

        return false;
    }

    /**
     * 构造响应
     *
     * @param code 响应码
     * @param msg  对应消息
     * @param data 响应数据
     * @author blank
     * @since 2018/3/19 下午12:27
     */
    public Result(int code, String msg, String callback, T data, boolean isSuccess) {
        this.code = code;
        this.msg = msg;
        this.callback = callback;
        this.data = data;
        this.isSuccess = isSuccess;
    }

    /**
     * 构造响应
     *
     * @param code 响应码
     * @param msg  对应消息
     * @param data 响应数据
     * @author blank
     * @since 2018/3/19 下午12:27
     */
    public Result(int code, String msg, String callback, T data, boolean isSuccess, boolean Pageable) {
        this.code = code;
        this.msg = msg;
        this.callback = callback;
        this.data = data;
        this.isSuccess = isSuccess;
    }

    /**
     * 构造响应
     *
     * @param code 响应码
     * @param msg  对应消息
     * @param data 响应数据
     * @author blank
     * @since 2018/3/19 下午12:27
     */
    public Result(int code, String msg, String callback, T data, boolean isSuccess, boolean Pageable,boolean logined) {
        this.code = code;
        this.msg = msg;
        this.callback = callback;
        this.data = data;
        this.isSuccess = isSuccess;
        this.logined = logined;
    }


    /**
     * 成功响应
     *
     * @return 成功
     */
    public static Result success() {
        return new Result();
    }


    /**
     * 成功响应
     *
     * @param pageable 是否可分页
     * @return 成功
     */
    public static Result success( boolean pageable) {
        return new Result(ResultCode.RESULT_SUCCESS.code, ResultCode.RESULT_SUCCESS.msg, null, null, true, pageable);
    }

    /**
     * 成功响应
     *
     * @param data     响应数据
     * @param pageable 是否可分页
     * @return 成功
     */
    public static Result success(Map<String, Object> data, boolean pageable) {
        return new Result(ResultCode.RESULT_SUCCESS.code, ResultCode.RESULT_SUCCESS.msg, null, data, true, pageable);
    }


    /**
     * 成功响应 自填成功 并自动填充成功说明
     *
     * @param anEnum 枚举
     * @return 失败
     */
    public static Result success(Enum anEnum) {
        return new Result(getCodeByEnum(anEnum), getMsgByEnum(anEnum), null, null);
    }


    /**
     * 成功响应 带 map
     *
     * @param data 响应数据
     * @return 成功
     */
    public static Result success(Map<String, Object> data) {
        return new Result(ResultCode.RESULT_SUCCESS.code, ResultCode.RESULT_SUCCESS.msg, null, data);
    }

    public static Result success(Object o) {
        return new Result(ResultCode.RESULT_SUCCESS.code, ResultCode.RESULT_SUCCESS.msg, null, o);
    }

    /**
     * 成功响应 自定义成功消息
     * @param msg 自定义的成功消息
     * @return 成功
     */
    public static Result success(String msg) {
        return new Result(ResultCode.RESULT_SUCCESS.code, msg, null, null);
    }


    /**
     * 失败响应
     *
     * @return 失败
     */
    public static Result failure() {
        return new Result(ResultCode.RESULT_FAILED.code, ResultCode.RESULT_FAILED.msg, null, null);
    }


    /**
     * 失败响应 带错误消息
     *
     * @param message 错误消息
     * @return 失败
     */
    public static Result failure(String message) {
        return new Result(ResultCode.RESULT_FAILED.code, message, null, null, false);
    }


    /**
     * 失败响应 自填错误码 并自动填充错误说明
     *
     * @return 失败
     */
    public static Result failure(int code) {
        return new Result(code, getMsgByCode(code), null, null, false);
    }

    /**
     * 失败响应 自填错误码 并自动填充错误说明
     *
     * @return 失败
     */
    public static Result failure(Enum code) {
        return new Result(getCodeByEnum(code), getMsgByEnum(code), null, null, false);
    }

    public static Result failure(Map<String,Object> paramMap){
        return new Result(getCodeByEnum(ResultCode.RESULT_FAILED), getMsgByEnum(ResultCode.RESULT_FAILED), null, paramMap, false);
    }
    /**
     * 失败响应 自填错误码 并自动填充错误说明
     *
     * @param code ENUM
     * @param msgDescribe 信息描述
     * @return 失败
     */
    public static Result failure(Enum code, String msgDescribe) {
        return new Result(getCodeByEnum(code), msgDescribe, null, null, false);
    }


    /**
     * 失败响应 自填错误码及错误说明 带 map
     *
     * @return 失败
     */
    public static Result failure(int code, String msgDescribe) {
        return new Result(code, msgDescribe, null, null, false);
    }

    /**
     * 失败响应 自填错误码及错误说明 带 map
     *
     * @return 失败
     */
    public static Result failure(int code, String msgDescribe,Map<String,Object> data) {
        return new Result(code, msgDescribe, null, data, false);
    }


    /**
     * 失败响应 带有必传参数提示响应消息 自填错误码及说明 返回
     *
     * @param param 必传参数
     * @return 失败
     */
    public static Result failureParam(String param) {
        return new Result(ResultCode.PARAM_IS_NEEDED.code, "请填必传参数 ==> " + param, null, null, false);
    }

    /**
     * 失败响应 带有必传参数提示响应消息 自填错误码及说明 返回
     *
     * @param param 必传参数
     * @return 失败
     */
    public static Result failureParamIsExit(String param) {
        return new Result(ResultCode.PARAM_IS_NEEDED.code, param+"已存在", null, null, false);
    }

    /**
     * 失败响应 带有必传参数提示响应消息 自填错误码及说明 返回
     *
     * @param param 必传参数
     * @param logined 是否登陆
     * @return 失败
     */
    public static Result failureParam(String param, boolean logined) {
        return new Result(ResultCode.PARAM_IS_NEEDED.code, "请填必传参数 ==> " + param, null, null, logined);
    }

    public static Result failure(Enum code,boolean logined){
        return new Result(getCodeByEnum(code),getMsgByEnum(code),null,null,false,false,logined);
    }


    /**
     * 结果返回
     * 只需这一个
     *
     * @return String
     */
    @SuppressWarnings("unchecked")
    public static Result getResult(Object... obj) {
        if (obj == null || obj.length == 0) {
            return Result.success();
        }
        //如果长度为1  并且是hashmap类型  则直接封装返回
        if (obj.length == 1 && obj[0] instanceof HashMap) {
            return Result.success(obj[0]);
        } else if (obj.length == 1 && obj[0] instanceof Enum) {
            return Result.getResultEnum((Enum) obj[0]);
        } else if (obj.length == 1 && obj[0] instanceof Boolean) {
            return Result.getResultBoolean((Boolean) obj[0]);
        } else if (obj.length == 1 && obj[0] instanceof Integer) {
            return Result.failure((Integer) obj[0]);
        }
        if (obj.length == 1) {
            return Result.success(obj[0]);
        }
        Map<String, Object> map = new HashMap<>();
        //返回多个对象
        for (int i = 0; i < obj.length; i = i + 2) {
            //奇数位必须传key 名称 必须是String类型
            if (!obj[i].getClass().getName().equals("java.lang.String")) {
                throw new RuntimeException("如果需要返回多个对象，请必须传key, value。eg: (\"token\", toke,\"userInfo\", userInfo,\"ui2\", userInfo2)");
            }
            map.put(obj[i].toString(), obj[i + 1]);
        }

        return Result.success(map);
    }

    private static Result getResultEnum(Enum e) {
        Result result = new Result();
        result.setCode(getCodeByEnum(e));
        result.setMsg(getMsgByEnum(e));
        result.setIsSuccess(isSuccess(e));
        return result;
    }

    /**
     * 根据 Boolean 值返回处理成功 或失败
     *
     * @param b Boolean 值
     * @return 处理成功 或失败
     * @author blank
     * @since 2018/5/24 上午9:57
     */
    private static Result getResultBoolean(Boolean b) {
        if (b) {
            return Result.success();
        }
        return Result.failure();
    }



    /**
     * 根据 code 返回对应的 msg
     *
     * @param code 状态碼
     * @return 状态码对应的 msg or null
     */
    static String getMsgByCode(int code) {

        ResultCode[] values = ResultCode.values();
        for (ResultCode resultCode : values) {

            if (resultCode.code == code) {
                return resultCode.msg;
            }
        }
        return null;
    }

    /**
     * 根据 msg 返回对应的 code
     *
     * @param msg 状态碼
     * @return 状态码对应的 code or 0
     */
    static int getCodeByMsg(String msg) {

        ResultCode[] values = ResultCode.values();
        for (ResultCode resultCode : values) {

            if (resultCode.msg.equals(msg)) {
                return resultCode.code;
            }
        }
        return 0;
    }

    /**
     * 根据  enum 返回对应的 msg
     *
     * @param anEnum 枚举
     * @return 状态码 or 0
     */
    static int getCodeByEnum(Enum anEnum) {

        ResultCode[] values = ResultCode.values();
        for (ResultCode resultCode : values) {

            if (resultCode == anEnum) {
                return resultCode.code;
            }
        }
        return 0;
    }

    /**
     * 根据  enum 返回对应的 msg
     *
     * @param anEnum 枚举
     * @return 状态码对应的 msg or null
     */
    static String getMsgByEnum(Enum anEnum) {

        ResultCode[] values = ResultCode.values();
        for (ResultCode resultCode : values) {

            if (resultCode == anEnum) {
                return resultCode.msg;
            }
        }
        return null;
    }


    /**
     * 根据 enum 返回对应的 自定义的true 还是false
     *
     * @param anEnum 枚举
     * @return true or false
     */
    static boolean isSuccess(Enum anEnum) {

        ResultCode[] values = ResultCode.values();
        for (ResultCode resultCode : values) {

            if (resultCode == anEnum) {
                return resultCode.isSuccess;
            }
        }
        return false;
    }


    public static void main(String[] args){
    }


}

